package isssr.dao.test;

import isssr.dao.exception.DAOException;
import isssr.dao.factory.DAOFactory;
import isssr.dao.interfaces.OrganizationalGoalDAO;
import isssr.entity.src.OrganizationalGoal;
import isssr.entity.src.User;

import java.lang.reflect.Field;
import java.util.ArrayList;

public class OGoalTestBuilder {
	
	private static Integer sequenceCounter = 0;
	
	private UserTestBuilder userBuilder;
	private ArrayList<OrganizationalGoal> persistedGoals;
	
	public OGoalTestBuilder()
	{
		this.persistedGoals = new ArrayList<OrganizationalGoal>();
		this.userBuilder = new UserTestBuilder();
	}
	

	private Integer getNextSequenceNumber()
	{
		return  sequenceCounter++;
	}
	
	public void registerGoal(OrganizationalGoal goal)
	{
		this.persistedGoals.add(goal);
	}
	
	public void unregisterGoal(OrganizationalGoal goal)
	{
		this.persistedGoals.remove(goal);
	}
	
	public OrganizationalGoal generateOrganizationalGoal(User owner, String title) throws DAOException
	{
		User finalOwner;
		if(owner == null)
		{
			finalOwner = userBuilder.generateUser();
			DAOFactory.getDAOFactory().getUserDAO().insert(finalOwner);
		}
		else
		{
			finalOwner = owner;
		}
		
		String finalTitle = (title != null ? title : "goal_title_" + getNextSequenceNumber());
		
		finalOwner.setFirstPassword("pass");
		
		OrganizationalGoal goal = new OrganizationalGoal(finalTitle, finalOwner);
		registerGoal(goal);
		
		return goal;
	}
	
	public OrganizationalGoal generateOrganizationalGoal(User owner) throws DAOException
	{
		return generateOrganizationalGoal(owner, null);
	}
	
	public OrganizationalGoal generateOrganizationalGoal(String title) throws DAOException
	{
		return generateOrganizationalGoal(null, title);
	}

	public OrganizationalGoal generateOrganizationalGoal() throws DAOException
	{
		return generateOrganizationalGoal(null, null);
	}
	
	public Object extractField(OrganizationalGoal goal, String fieldName)
	{
		Object finalValue = null;
		
		try
		{
			Object value = null;
			
			Field field = OrganizationalGoal.class.getDeclaredField("title");
			boolean fieldNotAccessible = ( ! field.isAccessible() );
			
			if(fieldNotAccessible) 
			{
				field.setAccessible(true);
			}
			
			value = field.get(goal);
			
			if(fieldNotAccessible)
			{
				field.setAccessible(false);
			}
			
			finalValue = value;
		}
		catch(ReflectiveOperationException ex)
		{
			ex.printStackTrace();
		}	
		
		return finalValue;
	}
	
	public boolean injectField(OrganizationalGoal goal, String fieldName, Object fieldValue)
	{
		
		boolean success = false;
		
		try
		{
			Field field = OrganizationalGoal.class.getDeclaredField("title");
			
			if(! field.getType().equals(fieldValue.getClass()))
				return false;
			
			boolean fieldNotAccessible = ( ! field.isAccessible() );
			
			if(fieldNotAccessible) 
			{
				field.setAccessible(true);
			}
			
			field.set(goal, fieldValue);
			
			if(fieldNotAccessible)
			{
				field.setAccessible(false);
			}
			
			success = true;
			
		}
		catch(ReflectiveOperationException ex)
		{
			ex.printStackTrace();
		}	
		
		return success;
	}
	
	public void cleanUp()
	{
		OrganizationalGoalDAO goalDAO = DAOFactory.getDAOFactory().getOrganizationalGoalDAO();
		
		for(OrganizationalGoal goal : this.persistedGoals)
		{
			try
			{
				goalDAO.delete(goal);
				
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
			}
		}
		
		this.userBuilder.cleanUp();
		
	}
	
/*
 * 
	private void setGoalTitle(OrganizationalGoal goal, String title) 
	{
		String finalTitle = ( title != null ? title : "goal_title_" + getNextSequenceNumber());
		
		try
		{
			Field field = OrganizationalGoal.class.getDeclaredField("title");
			boolean fieldNotAccessible = ( ! field.isAccessible() );
			
			if(fieldNotAccessible) 
			{
				field.setAccessible(true);
			}
			
			field.set(goal, finalTitle);
			
			if(fieldNotAccessible)
			{
				field.setAccessible(false);
			}
		}
		catch(ReflectiveOperationException ex)
		{
			ex.printStackTrace();
		}	
	}
	*/
}
